<!DOCTYPE html>
<html>

<head>
    <script src="js/konva.js"></script>
    <script src="js/jquery.js"></script>
    <script src="js/flowchart.js"></script>
    <meta charset="utf-8" />
    <title>Flowchart Demo</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
            background-color: #f0f0f0;
        }

        #container {
            padding: 20px;
        }
    </style>
</head>

<body>
    <div id="container"></div>
    <script>
        var width = window.innerWidth;
        var height = window.innerHeight;

        var stage = new Konva.Stage({
            container: 'container',
            width: width,
            height: height
        });
        var layer = new Konva.Layer();

        var sidePart = new Konva.Rect({
            x: width - 250 - 30,
            y: 30,
            width: 250,
            height: 500,
            fill: '#ffffff',
            stroke: '#ffe187',
            strokeWidth: 2
        });

        var template = [{
                type: "start",
                color: "red",
                text: "模型输入",
            },
            {
                type: "service",
                color: "",
                text: "内部服务",
            },
            {
                type: "connection",
                color: "",
                text: "连接分支",
            },
            {
                type: "condition",
                color: "",
                text: "判断分支",
            },
            {
                type: "end",
                color: "",
                text: "模型输出",
            },
        ];
        let startY = 30 + 20;
        let startX = width - 250 - 5;
        let elW = 200;
        let elH = 35;
        layer.add(sidePart);


        // draw connection line
        let drawConnectLineStart = function (evt) {
            if (evt.target.hasName("connectLine")) {
                let line = evt.target;
                evt.cancelBubble = true;
                stage._startDrapConnectLine = true;
                let mp = stage.getPointerPosition();
                let lp = line.getParent().absolutePosition();
                let h = line.height();
                let w = line.width();

                h = h == 0 ? 0 : elH;
                w = w == 0 ? 0 : elW;
                if (line._positionType == 'b' && h == 0) {
                    h = elH * 2;
                }
                if (line._positionType == 'r' && w == 0) {
                    w = elW * 2
                }
                stage._connectionLine = new Konva.Arrow({
                    name: "arrow",
                    x: 0,
                    y: 0,
                    points: [lp.x + w / 2, lp.y + h / 2, mp.x, mp.y],
                    fill: 'black',
                    stroke: 'black',
                    strokeWidth: 4
                });
                layer.add(stage._connectionLine);
                stage._connectionLine.moveToTop();
                stage._startNode = line;
                return;
            }
        }
        let drawConnectLineProcess = function (evt) {
            if (stage._startDrapConnectLine) {
                let mp = stage.getPointerPosition();
                let points = stage._connectionLine.points();
                points[2] = mp.x - 5;
                points[3] = mp.y - 5;
                stage._connectionLine.points(points);
                layer.draw();
            }
        }
        let drawConnectLineEnd = function (evt) {
            stage._startDrapConnectLine = false;
            stage._startNode = null;
            stage._connectionLine = null;
            evt.cancelBubble = true;
        };
        let chooseLine = function (evt) {
            if (evt.target.hasName("connectLine") && evt.target !== stage._startNode && stage._startNode) {
                // choose current line node as end
                let line = evt.target;
                let lp = line.getParent().absolutePosition();
                let h = line.height();
                let w = line.width();
                h = h == 0 ? 0 : elH;
                w = w == 0 ? 0 : elW;
                if (line._positionType == 'b' && h == 0) {
                    h = elH * 2;
                }
                if (line._positionType == 'r' && w == 0) {
                    w = elW * 2
                }
                let points = stage._connectionLine.points();
                points[2] = lp.x + w / 2;
                points[3] = lp.y + h / 2;
                stage._connectionLine.points(points);
                layer.draw();
                drawConnectLineEnd(evt)
            }
        }
        let lineClickHandler = function (evt) {
            if (stage._startDrapConnectLine) {
                chooseLine(evt);
            } else {
                drawConnectLineStart(evt);
            }
        }
        stage.on("mousemove", drawConnectLineProcess);
        //stage.on("mouseup", drawConnectLineEnd);


        let dragstartHandler = function (evt) {
            let group = evt.target;
            let newGroup = group.clone();
            group.parent.add(newGroup);
            group.off("dragstart");
            group.on("mousemove mouseover", function (e) {
                let mp = stage.getPointerPosition();
                let tp = e.target.absolutePosition();
                let h = elH;
                let w = elW;
                // 判断是在上还是在下
                let lineConfig = {
                    name: "connectLine",
                    stroke: '#44b1ffbf',
                    strokeWidth: 8,
                    shadowBlur: 5,
                    lineCap: 'round',
                    lineJoin: 'round'
                }
                let line = group.findOne(".connectLine");
                if (!line) {
                    line = new Konva.Line(lineConfig);
                    line.on("click tap", lineClickHandler);
                    group.add(line);
                }
                let flag = false;
                if ((mp.y > tp.y && mp.y < tp.y + 10) && (mp.x > tp.x + 20 && mp.x < tp.x + w - 20)) {
                    // 上
                    line.points([25, 2, w - 25, 2]);
                    line._positionType = "t"
                    flag = true;
                } else if ((mp.y < tp.y + h && mp.y > tp.y + h - 10) && (mp.x > tp.x + 20 && mp.x < tp.x +
                        w - 20)) {
                    // 下
                    line.points([25, h - 2, w - 25, h - 2]);
                    line._positionType = "b"
                    flag = true;
                } else if ((mp.y > tp.y && mp.y < tp.y + h) && (mp.x > tp.x && mp.x < tp.x + 20)) {
                    // 左
                    line.points([2, 10, 2, h - 10]);
                    line._positionType = "l"
                    flag = true;
                } else if ((mp.y > tp.y && mp.y < tp.y + h) && (mp.x > tp.x + w - 20 && mp.x < tp.x + w)) {
                    // 右
                    line.points([w - 2, 10, w - 2, h - 10]);
                    line._positionType = "r"
                    flag = true;
                }
                if (flag) {
                    line.moveToTop();
                    line.show();
                    layer.draw();
                }
            });
            group.on("mouseout", function (evt) {
                if (group.children) {
                    let line = group.findOne(".connectLine");
                    if (line && !stage._connectionLine) {
                        line.hide();
                    }
                }
            });
        }

        for (let i = 0; i < template.length; i++) {
            let tmp = template[i];
            let el = new Konva.Rect({
                name: "el",
                width: elW,
                height: elH,
                fill: tmp.color || '#ffffff',
                stroke: 'black',
                strokeWidth: 2
            });
            let text = new Konva.Text({
                width: elW,
                height: elH,
                text: tmp.text,
                padding: 10,
                fontSize: 16,
                align: "center",
                fill: 'black'
            });
            let group = new Konva.Group({
                x: startX,
                y: startY,
                draggable: true,
                name: "group"
            });
            group.on("dragstart", dragstartHandler);
            group.add(el);
            group.add(text);
            group.$data = $.extend({}, tmp);
            layer.add(group);
            startY = startY + elH + 20;
            console.log(group, group.toJSON())
        }

        let tr = new Konva.Transformer({
            resizeEnabled: false,
            rotateEnabled: false,
            borderStrokeWidth: 4
        });
        layer.add(tr);
        let selectHandler = function (evt) {
            let shape = evt.target;
            let group = evt.currentTarget;
            if (evt.target === stage) {
                tr.nodes([]);
                layer.draw();
                return;
            }
            if (evt.target.hasName("arrow")) {
                console.log(evt.target.absolutePosition())
                return;
            }

            tr.nodes([evt.target]);
            tr.moveToTop();
            layer.draw();
        }
        stage.on('click tap', selectHandler);
        // add the layer to the stage
        stage.add(layer);

        
    </script>
</body>

</html>